home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / ext / video.php < prev    next >
PHP Script  |  2010-05-19  |  19KB  |  509 lines

  1. <?php
  2. /**
  3.  * Send a requested VIDEO, AUDIO FILE or PLAYLIST to user from a redirected 'not found' request
  4.  * this script is used for file access from embed or external audio players
  5.  *
  6.  * 3 kind of audio file can be processed :
  7.  *    - audio files (.mp3, .wav...)
  8.  *    - existing playlist (.m3u files)
  9.  *    - PHP playlist (used by audio explorer scripts), named *playlist*.m3u[.xml]
  10.  *   - single mp3 playlist (used by audio explorer scripts),named *singleMP3*.mp3.xml, used to bypass flash player limitation (cannot read somme characters like "&"...)
  11.  * if a .xml extension is added on a m3u or a mp3 file, the actual output is converted to an XML playlist file designed for being red by flash player.
  12.  *
  13.  * All (mime) video files can be processed. Only simple "streaming" is supported (no playlist or XML stuff...)
  14.  *
  15.  * URI must be formated like "/ext/sess_$passedsessionId/resId$resId/[image/][w$width/][h$height/]urlencoded($filename)
  16.  * where "$id" is an active session id, and "urlencoded(filename)" is url-encoded requested
  17.  * file name (must include absolute path, and not relative path)
  18.  *
  19.  * If audio/$bitrate/ is specified, output file is reencoded with FFMPEG encoder
  20.  *
  21.  * If $filename is an existing m3u file, an modified m3u is sent to user, replacing song's filenames by
  22.  * reformated filenames (/external/sess_$id/...)
  23.  *
  24.  * If $fileName is *playlist*.m3u or *playlist*.m3u.xml,
  25.  *
  26.  * PHP version 5
  27.  *
  28.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  29.  * that is available through the world-wide-web at the following URI:
  30.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  31.  * the PHP License and are unable to obtain it through the web, please
  32.  * send a note to license@php.net so we can mail you a copy immediately.
  33.  *
  34.  * @category   NA
  35.  * @package    NA
  36.  * @author     Nicolas Bruley / Peer 2 World <contact@weezo.net>
  37.  * @copyright  2005-2009 Nicolas Bruley / Peer 2 World
  38.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  39.  * @version    CVS: $Id:$
  40.  * @link       http://www.weezo.net
  41.  * @since      File available since Release 1.0.0
  42.  */
  43.  
  44. define('SESSION_NAME_PREFIX','sess_');
  45. $resampledAudioFile=false;
  46. $bitrate=false;
  47.  
  48. /**
  49.  * @desc reencode video to flv using ffmpeg, and stream result to output
  50.  *
  51.  * @param string $completeFilename : original video file name
  52.  * @param array $params: optional parameters:
  53.  *           w & h: width & height (pixels)
  54.  *           q: output quality ("sameq","high","medium","low")
  55.  *           noSound: no sound
  56.  *           offset: offset from start
  57.  */
  58.  
  59.  
  60. /**
  61.  * @desc reencode video to flv using ffmpeg, and stream result to output
  62.  *
  63.  * @param string $completeFilename : original video file name
  64.  * @param array $params: w (width), h (height), q (quality), noSound(), chunkOffset(offset in seconds from begining, used by video chunking), chunkLength(seconds), offset(overriden by chunkOffset)
  65.  * @param int $height
  66.  * @param string $outputQuality
  67.  */
  68. function videoGenerateFlashVideo($completeFilename, $params=array()){
  69.     // Video size
  70.     $outputWidth =(isset($params['w']))?$params['w']:cfRGetVar('singleVideoWidth');
  71.     $outputHeight=(isset($params['h']))?$params['h']:cfRGetVar('singleVideoHeight');
  72.  
  73.     // Set even values for width & height
  74.     $outputHeight+=$outputHeight%2;
  75.     $outputWidth+=$outputWidth%2;
  76.  
  77.     // Compute video bitrate
  78.     switch ($outputWidth) {
  79.         case 640:
  80.             $br=400;break;
  81.         case 400:
  82.             $br=300;break;
  83.         case 160:
  84.             $br=25;    break;
  85.         default:
  86.             if(is_numeric($outputWidth)) {
  87.                 if($outputWidth<250) $br=max(floor(25*pow($outputWidth/160,2)),25); else $br=$outputWidth*3/4;
  88.             }
  89.             else $br=100;
  90.     }
  91.  
  92.     // Global quality
  93.     $outputQuality=(isset($params['q']))?$params['q']:cfRGetVar('flashOutputQuality');
  94.     switch ($outputQuality) {
  95.         case 'original':
  96.             $outputQuality='-sameq';
  97.             break;
  98.         case 'high':
  99.             $outputQuality='-b '.(3*$br).'k';
  100.             break;
  101.         case 'medium':
  102.             $outputQuality='-b '.(2*$br).'k';
  103.             break;
  104.         default:
  105.             $outputQuality='-b '.(1*$br).'k';
  106.             break;
  107.     }
  108.  
  109.     // Sound
  110.     if(!isset($params['noSound'])) $sound=' -async 1 -ar 11025 -ac 2'; else $sound=' -an';
  111.  
  112.     // Video Offset
  113.     // 1st use current chunk offset if passed by flash player
  114.     if(isset($params['chunkOffset']) && is_numeric($params['chunkOffset'])) $offset=' -ss '.$params['chunkOffset'];
  115.     // Then use initial offset passed by flash player
  116.     elseif(isset($params['offset']) && is_numeric($params['offset'])) $offset=' -ss '.$params['offset'];
  117.     // Then use resource-set offset
  118.     elseif(cfRGetVar('flashOutputOffset') && is_numeric(cfRGetVar('flashOutputOffset'))) $offset=' -ss '.cfRGetVar('flashOutputOffset').' ';
  119.     // Or start at begining of file
  120.     else $offset='';
  121.  
  122.     // Encoding duration: only limit if slicing video into chunks
  123.     if(cfIsWII()) unset($params['chunkLength']);
  124.     $duration=(isset($params['chunkLength']))?' -t '.($params['chunkLength']+1):'';
  125.  
  126.     // Ffmpeg command line
  127.     $cl='"'.cfFfmpegExe().'" -re -redelay 9 '.$offset.$duration.' -i "'.$completeFilename.'"  '.$outputQuality.$sound.' -f flv -s '.$outputWidth.'x'.$outputHeight.' - ';
  128.  
  129.     // Close session
  130.     wSession_write_close();
  131.  
  132.     // Set speed limit
  133.     $speedLimit=(int)((isset($params['downloadSpeedLimit']))?$params['downloadSpeedLimit']:cfUGetVar('downloadSpeedLimit'));
  134.     unset($_SESSION);
  135.  
  136.     // Launch ffmpeg
  137.     cfDebugUpdateBuffer('Launch ffmpeg: '.$cl);
  138.     cfStreamProc($cl,array('stdout'=>'stdout'),array('speedLimit'=>$speedLimit));
  139.     cfDebugSingle('End of flash reencoded streaming');
  140.     exit;
  141. }
  142.  
  143. /**
  144.  * @desc reencode video to WMV using ffmpeg, and stream result to output - to be used for Windows Mobile streaming
  145.  *
  146.  * @param string $completeFilename : original video file name
  147.  * @param int $width
  148.  * @param int $height
  149.  * @param string $outputQuality
  150.  */
  151. function videoGenerateWMVVideo($completeFilename, $params=array()){
  152.     // Video size
  153.     $outputWidth =(isset($params['w']))?$params['w']:cfRGetVar('singleVideoWidth');
  154.     $outputHeight=(isset($params['h']))?$params['h']:cfRGetVar('singleVideoHeight');
  155.  
  156.     // Set even values for width & height
  157.     $outputHeight+=$outputHeight%2;
  158.     $outputWidth+=$outputWidth%2;
  159.  
  160.     // Global quality
  161.     $outputQuality=(isset($params['q']))?$params['q']:cfRGetVar('flashOutputQuality');
  162.     switch ($outputQuality) {
  163.         case 'original':
  164.             $outputQuality='-sameq';
  165.             break;
  166.         case 'high':
  167.             $outputQuality='-b 256k';
  168.             break;
  169.         case 'medium':
  170.             $outputQuality='-b 128k';
  171.             break;
  172.         default:
  173.             $outputQuality='-b 64k';
  174.             break;
  175.     }
  176.  
  177.     // Sound
  178.     if(!isset($params['noSound'])) $sound=' -acodec wmav2 -ar 11025 -ac 2 -ab 24k'; else $sound=' -an';
  179.  
  180.     // Offset
  181.     if(isset($params['offset']) && is_numeric($params['offset'])) $offset=' -ss '.$params['offset'];
  182.     elseif(cfRGetVar('flashOutputOffset') && is_numeric(cfRGetVar('flashOutputOffset'))) $offset=' -ss '.cfRGetVar('flashOutputOffset').' ';
  183.     else $offset='';
  184.  
  185.     // Ffmpeg command line
  186.     $cl='"'.cfFfmpegExe().'" -re -redelay 9 '.$offset.' -y -i "'.$completeFilename.'" -vcodec wmv2 '.$outputQuality.$sound.' -f asf -s '.$outputWidth.'x'.$outputHeight.' - ';
  187.     // Close session
  188.     wSession_write_close();
  189.     $speedLimit=cfUGetVar('downloadSpeedLimit');
  190.     unset($_SESSION);
  191.  
  192.     // Launch ffmpeg
  193.     cfStreamProc($cl,array('stdout'=>'stdout'),array('speedLimit'=>$speedLimit));
  194.     exit;
  195. }
  196.  
  197. /**
  198.  * @desc Check published image access rights and send to output
  199.  *
  200.  * @param array $uri: parsed URI ("previewImg"=>1 to generate a snapshot)
  201.  */
  202. function videoPublished($uri){
  203.     $id=$uri['dlToken'];
  204.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  205.     $tokenList=efTokensRead();
  206.  
  207.     // If link is not published video or streamed direct link, exit
  208.     if(!(@$token=$tokenList[$id])) cfLog('invalid published video id ('.$id.')',LOG_DBG);
  209.     if($token['type']!=='publishVideo' && ($token['type']!=='directLink' || @$token['streaming']!=='video')) cfLog('invalid published video id ('.$id.')',LOG_DBG);
  210.  
  211.     // Check file's existence
  212.     if(!is_file($token['filename'])) logError('perempted published image ('.$token['filename'].')');
  213.  
  214.     // Video screenshot
  215.     if(isset($uri['previewImg'])){
  216.         require_once(INCLUDE_DIR.'explorerFunctions.php');
  217.         header('Content-type: image/jpg');
  218.         efMakeVideoThumbnail($token['filename'],false,$token['w'],$token['h'],70,30);
  219.         exit;
  220.     }
  221.  
  222.     // Increase number of downloads and save
  223.     $tokenList[$id]['limitNb']--;
  224.     efTokensWrite($tokenList);
  225.  
  226.     // Set options
  227.     $options=array('w'=>$token['w'],'h'=>$token['h'],'q'=>$token['flashOutputQuality']);
  228.     $options+=array('chunkLength'=>(isset($uri['chunkLength']))?$uri['chunkLength']:300);
  229.     $options+=array('downloadSpeedLimit'=>0);
  230.     if(isset($uri['offset'])) $options+=array('offset'=>$uri['offset']);
  231.     if(isset($uri['chunkOffset'])) $options+=array('chunkOffset'=>$uri['chunkOffset']);
  232.  
  233.     // Generate video
  234.     if(cfIsMobile('iPhone','wii')) videoGenerateWMVVideo($token['filename'],$options);
  235.     else videoGenerateFlashVideo($token['filename'],$options);
  236. }
  237.  
  238.  
  239. require(INCLUDE_DIR.'explorerFunctions.php');
  240. require(INCLUDE_DIR.'mime_type.php');
  241.  
  242.  
  243. // Decode and parse URI
  244. $uri=cfParseExtURI();
  245.  
  246. // Debug
  247. cfDebugSetBuffer('video',$uri);
  248. //cfDbg($uri,1);
  249.  
  250. // Published video
  251. if(isset($uri['dlToken'])) videoPublished($uri);
  252.  
  253. // Verify minimum data presence
  254. if(!isset($uri['video']) || !isset($uri['sess']) || !isset($uri['resId']) || !isset($uri['file'])) cfHTTPError(403);
  255.  
  256. cfLog('extAccess.php: file requested : '.$_SERVER['REQUEST_URI'],LOG_DBG);
  257.  
  258. // verify that passed session ID exists
  259. if(!($handle = opendir(wSession_save_path()))) cfHTTPError(403);
  260. $found=false;
  261. while ((($file = @readdir($handle))!==false) && !$found){
  262.     if(is_file(wSession_save_path().'/'.$file) && $uri['sess']==$file) $found=true;
  263. }
  264. closedir($handle);
  265.  
  266. // If passed session not found, display 404 and exit
  267. if(!$found) cfHTTPError(404);
  268.  
  269. /**
  270.  * START SESSION
  271.  */
  272. $uri['sess']=substr($uri['sess'],strlen(SESSION_NAME_PREFIX));
  273. wSession_id($uri['sess']);
  274. wSession_start();
  275.  
  276. // verifie that client's IP match with session's IP
  277. if($_SERVER['REMOTE_ADDR']!=$_SESSION['accountIP'] && cfGGetVar('disableClientSessionIPControl')!='true' && !isset($_SERVER['HTTPS'])) {
  278.     cfLog('extAccess.php: passed session id does not match with IP => 403',LOG_ER);
  279.     cfHTTPError(403);
  280. }
  281.  
  282. // Set active resource id
  283. if(!is_numeric($uri['resId']) || !isset($_SESSION['res'][$uri['resId']]) || !is_array($_SESSION['res'][$uri['resId']]))  cfHTTPError(403);
  284. $_SESSION['activeResourceId']=$uri['resId'];
  285.  
  286. /**
  287.  * unencode filename
  288.  */
  289.  
  290. // b64 encoded
  291. if(isset($uri['b64'])) $completeFilename=base64_decode($uri['file']);
  292.  
  293. // if encoding-decoding doesn't work then string is already utf8-encoded
  294. elseif(cfUTF8Encode(cfUTF8Decode($uri['file'],true,false,false,2048),false,true)!=$uri['file'])
  295.     $completeFilename=$uri['file'];
  296. else
  297.     $completeFilename=cfUTF8Decode($uri['file'],true,true,false,2048);
  298.  
  299. $completeFilename=str_replace('&','&',$completeFilename);
  300. $completeFilename=str_replace('*weezoSharp*','#',$completeFilename);
  301.  
  302. // Restore real path
  303. if(cfSharedMode('list') && strpos($completeFilename,'*resourceBasePath*')!==false) $completeFilename=cfSharedCompleteFilename($completeFilename);
  304. else $completeFilename=str_replace('*resourceBasePath*',cfRGetVar('path'),$completeFilename);
  305. $completeFilename=str_replace('*resourceDataDirBasePath*',cfAppResourceDir(),$completeFilename);
  306.  
  307. // Remove rnd part for playlists, singleMp3 and singleVideo
  308. if(substr($completeFilename,-17)=='*singleVideo*.xml')
  309.     $completeFilename=substr($completeFilename,strrpos($completeFilename,'*',-10));
  310.  
  311. /**
  312.  * Flash single video XML playlist
  313.  */
  314. if($completeFilename=='*singleVideo*.xml'){
  315.     // HEADER
  316.     header('Content-Type:text/xml');
  317.     header("Pragma: public"); // Required by IE6/7 in SSL mode
  318.     header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // No cache
  319.  
  320.  
  321.     $src=cfRGetVar('singleVideo');
  322.     if(isset($uri['chunkOffset']) && strpos($src,'/file'))    $src=substr($src,0,strpos($src,'/file')).'/chunkOffset.'.$uri['chunkOffset'].substr($src,strpos($src,'/file'));
  323.     if(isset($uri['chunkOffset']) && strpos($src,'/b64'))    $src=substr($src,0,strpos($src,'/b64')).'/chunkOffset.'.$uri['chunkOffset'].substr($src,strpos($src,'/b64'));
  324.     $src=cfHostName().cfUTF8Encode($src);
  325.  
  326.     $xml ='<?xml version="1.0" encoding="utf-8"?>'."\n".'<playlist volume="'.((cfUGetVar('audioVolume')!==false)?cfUGetVar('audioVolume'):'80').'">'."\n<video file=\"".$src."\"/>\n";
  327.     // Subtitles
  328.     if(cfRGetVar('singleVideoSubtitles')) {
  329.         require_once(INCLUDE_DIR.'subtitlesFunctions.php');
  330.         $xml.= sfGenerateXMLSubs(cfRGetVar('singleVideoSubtitles'));
  331.     }
  332.     $xml.="\n</playlist>";
  333.     cfDebugUpdateBuffer($xml);
  334.     die($xml);
  335. }
  336.  
  337. /**
  338.  * Video
  339.  */
  340.  
  341. // Flash video real-time reencoding
  342. $flashReencode=isset($uri['flv']);
  343.  
  344. // WMV video real-time reencoding
  345. $WMVReencode=isset($uri['wmv']);
  346. if($WMVReencode) $completeFilename=substr($completeFilename,0,-12); // Remove trailing ".convert.wmv"
  347.  
  348. $ffmpegReencode=$WMVReencode||$flashReencode;
  349.  
  350.  
  351. /***********************************************************************************************************************************
  352.  * Check file access rights
  353.  **********************************************************************************************************************************/
  354.  
  355. // Resource specific file source and rights function : bypass common file's existence and access rights
  356. // and (may) replace given file name by real file name
  357. if(cfRGetVar('extAccessFunction')) {
  358.     $extAccessFunction = create_function('$completeFilename', cfRGetVar('extAccessFunction'));
  359.     if(!($completeFilename=$extAccessFunction($completeFilename))) cfHTTPError(404);
  360. }
  361. // Check file's existence and access rights
  362. else{
  363.     // If file doesn't exist, Display 404 and exit
  364.     if(!file_exists($completeFilename))    cfHTTPError(404);
  365.  
  366.     // If file download not allowed, Display 404 and exit
  367.     if(!cfFileRights($completeFilename,'download')) cfHTTPError(403);
  368.  
  369.     // If file is not a video file, Display 404 and exit
  370.     if($mt=mimeType(cfFileExtension($completeFilename))) $type=substr($mt,0,strpos($mt,"/")); else $type=false;
  371.     if($type!='video') cfHTTPError(403);
  372. }
  373.  
  374. /**
  375.  * iPhone-specific video processing
  376.  */
  377. if(isset($uri['format']) && in_array($uri['format'],array('m3u8sa','m3u8','ts'))) require(cfAppDocRoot().'/ext/videoIPhone.php');
  378.  
  379.  
  380. // Caching
  381. if(substr($completeFilename,0,13)=='*singleVideo*' || $ffmpegReencode) $cacheFile=false; else $cacheFile=true;
  382.  
  383. // Check if a range request can be satified
  384. $acceptRange=!$ffmpegReencode;
  385.  
  386. // Check if client did a range request
  387. $clientHeaders=getallheaders();
  388. $range=((isset($clientHeaders['Range']) && strtolower(substr($clientHeaders['Range'],0,6)=='bytes='))?trim(substr($clientHeaders['Range'],6)):$range=false);
  389.  
  390. // process range request
  391. if($range && strpos($range,'-')!==false && $range!='0-'){
  392.     // Reject range requests on resampled files or m3u or xml
  393.     if(!$acceptRange){
  394.         header('HTTP/1.1 416 Requested Range Not Satisfiable');
  395.         $range=false;
  396.     }
  397.     $range=trim($range);
  398.     $fileSize=cfFileSize($completeFilename);
  399.  
  400.     // From
  401.     $from=substr($range,0,strpos($range,'-'));
  402.     if(!strlen($from)) $from=0;
  403.     if(!is_numeric($from) || $from>$fileSize) $rangeErr=true;
  404.  
  405.     // To
  406.     $rto=substr($range,strpos($range,'-')+1);
  407.     if(!strlen($rto)) {
  408.         $to = $fileSize-1;
  409.     }
  410.     else $to=$rto;
  411.     if($to+1>$fileSize || $to<$from) $rangeErr=true;
  412.     $content_size = 1 + $to - $from;
  413.  
  414.     // Incorrect range
  415.     if(isset($rangeErr)){
  416.         header('HTTP/1.1 416 Requested Range Not Satisfiable');
  417.         $range=false;
  418.         cfDebugUpdateBuffer('Incorrect range requested: '.$from.'-'.$to);
  419.     }
  420.     else{
  421.         header('HTTP/1.1 206 Partial Content');
  422.         header("Content-Range: bytes $from-$to/$fileSize");
  423.         $contentLength=$content_size;
  424.         $range=array('from'=>$from,'to'=>1+$to);
  425.         cfDebugUpdateBuffer('Range requested: '.$from.'-'.$to);
  426.     }
  427. }
  428. else $range=false;
  429.  
  430. // Set content-length if possible
  431. if(!$range){
  432.     if(cfFileExtension($completeFilename)=='m3u' || cfFileExtension($completeFilename)=='xml') $contentLength=strlen($convertedM3UFile);
  433. }
  434.  
  435.  
  436. /***********************************************************************************************************************************
  437.  * HEADERS
  438.  **********************************************************************************************************************************/
  439.  
  440. // Mime type
  441. if($flashReencode) header('Content-Type: video/x-flv'); // any video format reencoded to FLV
  442. if($WMVReencode) header('Content-Type: video/x-ms-wmv'); // any video format reencoded to WMV
  443. elseif(isset($uri['image'])) header('Content-Type: image/gif'); // Screenshot
  444. else header('Content-Type: '.mimeType($completeFilename)); // Not reencoded video
  445.  
  446. // Cache
  447. if($cacheFile){
  448.     header("Pragma:"); // Do not remove, required by IE in SSL mode
  449.     header('Cache-Control: private');
  450.     header('ETag: "'.md5($completeFilename).'"');
  451.     header('Last-Modified: '.gmdate("D, d M Y H:i:s",@filemtime($completeFilename)).' GMT');
  452.     header('Expires: '.gmdate("D, d M Y H:i:s",time()+3600*24*100).' GMT');
  453. }
  454. // No cache
  455. else{
  456.     if(cfIsWII()) header("Pragma: no-cache");
  457.     else header("Pragma:"); // Do not remove, required by IE in SSL mode
  458.     header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
  459.     header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  460.     if(cfIsWII()) header('Content-Length: 999999999');
  461. }
  462.  
  463.  
  464. // Still image (screenshot) generate screenshot (and exit)
  465. if(isset($uri['image'])) {
  466.     wSession_write_close();
  467.     // Generate and send thumbnail to output
  468.     header('Content-type: image/jpg');
  469.     if(efMakeVideoThumbnail($completeFilename,'',isset($uri['w'])?$uri['w']:0,isset($uri['h'])?$uri['h']:0,0,20)) exit;
  470.  
  471.     // If failure, generate
  472.     $im = imagecreate($width, $height);
  473.     imagefilledrectangle($im, 0, 0, $width, $height, imagecolorallocate($im, 0, 0, 0));
  474.     imagestring($im,5,$width/2-8, $height/2-8,'?',imagecolorallocate($im, 255, 255, 255));
  475.     imagejpeg($im);
  476.     imagedestroy($im);
  477.     exit;
  478. }
  479.  
  480.  
  481. // Video
  482. header('X-Powered-By:');
  483. header('Content-Disposition: inline; filename="'.cfUTF8Encode(basename($completeFilename),false,false).'"');
  484. if($acceptRange) header("Accept-Ranges: bytes"); else header("Accept-Ranges: none");
  485. if(isset($contentLength)) header('Content-Length:'.$contentLength);
  486.  
  487. // Log in events log
  488. cfLog('/ext/video.php: file download initiated:'.$completeFilename,LOG_DBG);
  489.  
  490. // Log in viewed content history
  491. cfLogContentAccess($completeFilename);
  492.  
  493. // Debug
  494. cfDebugUpdateBuffer('Headers sent, requested file: '.$completeFilename);
  495.  
  496. // Set speed limit
  497. $speedLimit=cfUGetVar('downloadSpeedLimit');
  498.  
  499. // Real-time ffmpeg video flash reencoding (then exit)
  500. if($flashReencode) videoGenerateFlashVideo($completeFilename, $uri);
  501.  
  502. // Real-time ffmpeg video flash reencoding (then exit)
  503. if($WMVReencode) videoGenerateWMVVideo($completeFilename, $uri);
  504.  
  505. // Stream raw file
  506. if($range) $contentLength=$range['to']-$range['from']; else $contentLength=filesize($completeFilename);
  507. header('Content-Length:'.$contentLength);
  508. cfStreamFile($completeFilename,false,$speedLimit,$range);
  509. ?>